package com.xiaomazi.order.service.impl;

import cn.hutool.json.JSONUtil;
import com.github.wxpay.sdk.WXPayUtil;
import com.xiaomazi.common.utils.R;
import com.xiaomazi.order.entity.Order;
import com.xiaomazi.order.service.OrderService;
import com.xiaomazi.order.utils.HttpClient;
import com.xiaomazi.order.utils.WChatConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaomazi.order.entity.PayLog;
import com.xiaomazi.order.mapper.PayLogMapper;
import com.xiaomazi.order.service.PayLogService;
import org.springframework.transaction.annotation.Transactional;

import static com.xiaomazi.order.constants.WeChatConstant.CREATE_PAY_CODE_URL;
import static com.xiaomazi.order.constants.WeChatConstant.SELECT_PAT_STATUS_URL;
import static com.xiaomazi.order.constants.WeChatConstant.STATUS_SUCCESS;

@Service
public class PayLogServiceImpl extends ServiceImpl<PayLogMapper, PayLog> implements PayLogService{


    @Autowired
    private WChatConfiguration wChatConfiguration;

    @Autowired
    private OrderService orderService;

    /**
     * 生成微信支付二维码接口
     * @param orderNo 订单号
     * @return map包含二维码地址，还有其他需要的信息
     */
    @Override
    public R createNative(String orderNo) {
        try {
            Order order = orderService.query().eq("order_no", orderNo).one();
            Map map = new HashMap<>();
            map.put("appid",wChatConfiguration.getAppid());
            map.put("mch_id", wChatConfiguration.getPartner());
            map.put("nonce_str", WXPayUtil.generateNonceStr());
            map.put("body",order.getCourseTitle());
            map.put("out_trade_no", orderNo); //订单号
            map.put("total_fee", order.getTotalFee().multiply(new BigDecimal("100")).longValue()+"");
            map.put("spbill_create_ip", "127.0.0.1");
            map.put("notify_url", wChatConfiguration.getNotifyurl()+"\n");
            map.put("trade_type", "NATIVE");
            HttpClient client = new HttpClient(CREATE_PAY_CODE_URL);

            client.setXmlParam(WXPayUtil.generateSignedXml(map,wChatConfiguration.getPartnerkey()));
            client.setHttps(true);
            //执行post请求发送
            client.post();

            String xml = client.getContent();

            Map<String,String> resultMap = WXPayUtil.xmlToMap(xml);
            //最终返回数据 的封装
            Map<String,Object> result = new HashMap();
            result.put("out_trade_no", orderNo);
            result.put("course_id", order.getCourseId());
            result.put("total_fee", order.getTotalFee());
            result.put("result_code", resultMap.get("result_code"));  //返回二维码操作状态码
            result.put("code_url", resultMap.get("code_url"));        //二维码地址

            return R.ok().data(result);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询订单支付状态
     * @param orderNo 订单号 根据订单号查询 支付状态
     * @return message支付状态 [支付成功 支付出错了 支付中]
     */
    @Override
    public R queryPayStatus(String orderNo) {
        Map<String, String> weChatInfo = sendHttpRequestToWeChat(orderNo);
        System.out.println("*****查询订单状态map集合:"+weChatInfo);
        if (null == weChatInfo){
            return R.error().message("支付出错了");
        }
        if (weChatInfo.get("trade_state").equals(STATUS_SUCCESS)){
            updateOrderStatusAndSavePayLog(orderNo, weChatInfo);
            return R.ok().message("支付成功");
        }
        return R.ok().code(25000).message("支付中");
    }

    @Transactional
    public void updateOrderStatusAndSavePayLog(String orderNo, Map<String, String> weChatInfo) {
        String oId = weChatInfo.get("out_trade_no");
        Order order = orderService.query().eq("order_no", oId).one();
        //更新订单表订单状态
        if(order.getStatus().intValue() != 1) {
            order.setStatus((byte) 1);//1代表已经支付
            orderService.updateById(order);

            PayLog payLog = new PayLog();
            payLog.setOrderNo(orderNo);  //订单号
            payLog.setPayTime(new Date()); //订单完成时间
            payLog.setPayType((byte) 1);//支付类型 1微信
            payLog.setTotalFee(order.getTotalFee());//总金额(分)

            payLog.setTradeState(weChatInfo.get("trade_state"));//支付状态
            payLog.setTransactionId(weChatInfo.get("transaction_id")); //流水号
            payLog.setAttr(JSONUtil.toJsonStr(weChatInfo));

            this.save(payLog);
        }
    }

    private Map<String, String> sendHttpRequestToWeChat(String orderNo) {
        try {
            //1、封装参数
            Map<String, String> m = new HashMap<>();
            m.put("appid",wChatConfiguration.getAppid());
            m.put("mch_id", wChatConfiguration.getPartner());
            m.put("out_trade_no", orderNo);
            m.put("nonce_str", WXPayUtil.generateNonceStr());

            //2 发送httpclient
            HttpClient client = new HttpClient(SELECT_PAT_STATUS_URL);
            client.setXmlParam(WXPayUtil.generateSignedXml(m,wChatConfiguration.getPartnerkey()));
            client.setHttps(true);
            client.post();

            //3 得到请求返回内容
            String xml = client.getContent();
            Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
            return resultMap;
        }catch(Exception e) {
            return null;
        }
    }
}
